package com.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;


public class DbUtil {
    public static String getMysql(String db) {
        InputStream inputStream = com.util.DbUtil.class.getClassLoader().getResourceAsStream("Mysql.properties");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
            return properties.get(db).toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    static {
        try {
            Class.forName(getMysql("db.ClassName"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Connection getConn() throws SQLException {
        return DriverManager.getConnection(getMysql("db.url"), getMysql("db.name"), getMysql("db.pwd"));
    }

    public void getClose(Connection connection, PreparedStatement pre, ResultSet resultSet) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pre != null) {
            try {
                pre.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (resultSet != null)
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    }

    Connection connection = null;
    PreparedStatement pre = null;
    ResultSet resultSet = null;

    public int executeUpdate(String sql, Object[] objects) throws SQLException {
        try {
            this.connection = getConn();
            this.pre = this.connection.prepareStatement(sql);
            if (objects != null) {
                for (int i = 1; i <= objects.length; i++) {
                    this.pre.setObject(i, objects[i - 1]);
                }
            }
            return this.pre.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        } finally {

            getClose(this.connection, this.pre, null);
        }
    }

    public int executeUpdateAll(String sql, Object[] objects) throws SQLException {
        try {
            this.connection = getConn();
            this.pre = this.connection.prepareStatement(sql, 1);
            if (objects != null) {
                for (int j = 1; j <= objects.length; j++) {
                    this.pre.setObject(j, objects[j - 1]);
                }
            }
            int i = this.pre.executeUpdate();
            this.resultSet = this.pre.getGeneratedKeys();
            if (this.resultSet.next()) {
                return this.resultSet.getInt(i);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        } finally {

            getClose(this.connection, this.pre, this.resultSet);
        }
        return 0;
    }

    public List<Map> executeQuery(String sql, Object[] args) throws SQLException {
        try {
            this.connection = getConn();
            this.pre = this.connection.prepareStatement(sql);
            if (args != null) {
                for (int i = 1; i <= args.length; i++) {
                    this.pre.setObject(i, args[i - 1]);
                }
            }
            this.resultSet = this.pre.executeQuery();
            ResultSetMetaData resultSetMetaData = this.pre.getMetaData();
            List<Map> list = new ArrayList<>();
            while (this.resultSet.next()) {
                Map<Object, Object> map = new HashMap<>();
                for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
                    map.put(resultSetMetaData.getColumnName(i).toLowerCase(), this.resultSet.getObject(i));
                }
                list.add(map);
            }
            return list;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw throwables;
        } finally {
            getClose(this.connection, this.pre, this.resultSet);
        }
    }
}